#include "CCSlotTransform.h"
#include "CCSpineGlobal.h"
#include "CCSkeletalSprite.h"
#include "CCSpineSprite.h"



CCSlotTransform::CCSlotTransform() {
}

CCSlotTransform::CCSlotTransform(CCSlot* slot) :
_slot(slot) {
}

CCSlotTransform::~CCSlotTransform() {
    m_skfList.clear();
    m_ckfList.clear();
}

CCSlotTransform* CCSlotTransform::create(CCSlot* slot) {
	CCSlotTransform* bt = new CCSlotTransform(slot);
	return (CCSlotTransform*)bt->autorelease();
}

void CCSlotTransform::addSkinKeyFrame(SkinKeyFrame kf) {
	m_skfList.push_back(kf);
}

void CCSlotTransform::addColorKeyFrame(ColorKeyFrame kf) {
	m_ckfList.push_back(kf);
}

void CCSlotTransform::populateFrame(float time) {
	// process skin frame
	{
		// set time to current time
		m_currentSkin.time = time;
		m_currentSkin.valid = true;
		
		// if empty, just set to zero
		// if not, found key frame, do interpolation if needed
		if(m_skfList.empty()) {
			m_currentSkin.valid = false;
		} else {
			SkinKeyFrameList::iterator iter = m_skfList.begin();
			for(; iter != m_skfList.end(); iter++) {
				SkinKeyFrame& kf = *iter;
				if(time < kf.time) {
					if(iter == m_skfList.begin()) {
						m_currentSkin.attachmentName = kf.attachmentName;
					} else {
						SkinKeyFrame& prevKf = *(iter - 1);
						float percent = getInterpolationTime(prevKf.time, kf.time, time, prevKf.interpolator);
						if(percent >= 1)
							m_currentSkin.attachmentName = kf.attachmentName;
						else
							m_currentSkin.attachmentName = prevKf.attachmentName;
					}
					break;
				} else if(time == kf.time) {
					m_currentSkin = kf;
					break;
				}
			}
			
			// if exceed last one
			if(iter == m_skfList.end()) {
				m_currentSkin.attachmentName = m_skfList.rbegin()->attachmentName;
			}
		}
	}
	
	// process color frame
	{
		// set time to current time
		m_currentColor.time = time;
		m_currentColor.valid = true;
		
		// if empty, just set to zero
		// if not, found key frame, do interpolation if needed
		if(m_ckfList.empty()) {
			m_currentColor.valid = false;
		} else {
			ColorKeyFrameList::iterator iter = m_ckfList.begin();
			for(; iter != m_ckfList.end(); iter++) {
				ColorKeyFrame& kf = *iter;
				if(time < kf.time) {
					if(iter == m_ckfList.begin()) {
						m_currentColor.color = kf.color;
					} else {
						ColorKeyFrame& prevKf = *(iter - 1);
						float percent = getInterpolationTime(prevKf.time, kf.time, time, prevKf.interpolator);
						
                        //m_currentColor.color = t.x * (kf.color - prevKf.color) + prevKf.color;
                         
                         m_currentColor.color.r= percent * (kf.color.r - prevKf.color.r) + prevKf.color.r;
                         m_currentColor.color.g= percent * (kf.color.g - prevKf.color.g) + prevKf.color.g;
                         m_currentColor.color.b= percent * (kf.color.b - prevKf.color.b) + prevKf.color.b;
                         m_currentColor.color.a= percent * (kf.color.a - prevKf.color.a) + prevKf.color.a;
					}
					break;
				} else if(time == kf.time) {
					m_currentColor = kf;
					break;
				}
			}
			
			// if exceed last one
			if(iter == m_ckfList.end()) {
				m_currentColor.color = m_ckfList.rbegin()->color;
			}
		}
	}
}

void CCSlotTransform::applyTo(CCSkeletalSprite* owner,float alpha) {
	
	// get state of this owner
	SlotState& state = _slot->getState(owner);
    //SlotState& original = slot->getOriginalState();
	
	// check sprite
    /*
	if(!sprite) 
		return false;*/
	
	// set skin texture
	if(m_currentSkin.valid && !_slot->hasFlag(CCSlot::FIXED_ATTACHMENT) && alpha>0.5f) {
        state.activeAttachmentName = m_currentSkin.attachmentName;
	}
    
	// set color
	if(m_currentColor.valid && !_slot->hasFlag(CCSlot::FIXED_COLOR) && alpha>0.5f) {
        state.color = m_currentColor.color;
        /*
        state.color.r+=(m_currentColor.color.r-original.color.r)*alpha;
        state.color.g+=(m_currentColor.color.g-original.color.g)*alpha;
        state.color.b+=(m_currentColor.color.b-original.color.b)*alpha;
        state.color.a+=(m_currentColor.color.a-original.color.a)*alpha;*/
	}
}


